import { Ionicons } from '@expo/vector-icons';
import { useFocusEffect, useRouter, Link } from 'expo-router';
import { useCallback, useEffect, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  FlatList,
  ListRenderItem,
  Pressable,
  StyleSheet,
  Switch,
  Text,
  TextInput,
  View,
} from 'react-native';
import { Image } from 'expo-image';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { resolveAssetUrl } from '@/constants/config';

import { useAuth } from '@/context/auth-context';
import { apiRequest, apiRequestWithMeta, ApiError } from '@/utils/api';

type PaginationMeta = {
  page: number;
  page_size: number;
  total: number;
};

type ApiAsset = {
  id: number;
  preview_url?: string;
  thumb_url?: string;
  original_url?: string;
};

type ProductImage = {
  id: number;
  sort_order: number;
  is_preview?: boolean;
  asset_id?: number;
};

type MerchantProduct = {
  id: number;
  title: string;
  type: string;
  description: string;
  price: number;
  cover_asset_id?: number | null;
  cover_asset?: ApiAsset | null;
  images?: ProductImage[];
  is_published: boolean;
  orders_count: number;
  units_sold: number;
  total_revenue: number;
};

const PAGE_SIZE = 10;
const palette = {
  background: '#fff7fb',
  surface: '#ffffff',
  accent: '#ff8fb1',
  accentDeep: '#ff6a9b',
  textPrimary: '#2f1f2b',
  textMuted: '#6a566a',
  border: 'rgba(214, 106, 138, 0.18)',
  danger: '#d64f7c',
};

const emptyStats = { orders_count: 0, units_sold: 0, total_revenue: 0 };

export default function MerchantProductsScreen() {
  const router = useRouter();
  const { merchantToken: token, setViewMode } = useAuth();

  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [products, setProducts] = useState<MerchantProduct[]>([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [isInitialLoading, setInitialLoading] = useState(true);
  const [isRefreshing, setRefreshing] = useState(false);
  const [isLoadingMore, setLoadingMore] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [updatingId, setUpdatingId] = useState<number | null>(null);

  useEffect(() => {
    const handler = setTimeout(() => setDebouncedSearch(search.trim()), 400);
    return () => clearTimeout(handler);
  }, [search]);

  const normalizeProduct = useCallback((item: MerchantProduct): MerchantProduct => {
    return {
      ...item,
      price: Number(item.price ?? 0),
      orders_count: Number(item.orders_count ?? emptyStats.orders_count),
      units_sold: Number(item.units_sold ?? emptyStats.units_sold),
      total_revenue: Number(item.total_revenue ?? emptyStats.total_revenue),
    };
  }, []);

  const fetchProducts = useCallback(
    async (targetPage: number, mode: 'replace' | 'append') => {
      if (!token) {
        setError('登录状态无效，请重新登录');
        return;
      }

      if (mode === 'append') {
        setLoadingMore(true);
      } else if (mode === 'replace' && !isInitialLoading) {
        setRefreshing(true);
      } else {
        setInitialLoading(true);
      }

      try {
        const { data, meta } = await apiRequestWithMeta<MerchantProduct[], PaginationMeta>(
          '/products',
          {
            token,
            query: {
              page: targetPage,
              page_size: PAGE_SIZE,
              search: debouncedSearch || undefined,
            },
          },
        );

        const normalized = data.map(normalizeProduct);

        setProducts((prev) => (mode === 'append' ? [...prev, ...normalized] : normalized));
        setPage(targetPage);

        const totalItems = typeof meta?.total === 'number' ? meta.total : normalized.length;
        const pageSize = meta?.page_size ?? PAGE_SIZE;
        setHasMore(targetPage * pageSize < totalItems);
        setError(null);
      } catch (err) {
        if (err instanceof ApiError && err.status === 401) {
          router.replace({ pathname: '/(auth)/login', params: { channel: 'merchant', redirect: '/(merchant)/products' } });
          return;
        }
        const message = err instanceof Error ? err.message : '商品数据加载失败，请稍后重试';
        setError(message);
      } finally {
        setInitialLoading(false);
        setRefreshing(false);
        setLoadingMore(false);
      }
    },
    [debouncedSearch, isInitialLoading, normalizeProduct, router, token],
  );

  useFocusEffect(
    useCallback(() => {
      fetchProducts(1, 'replace');
    }, [fetchProducts]),
  );

  const handleRefresh = useCallback(() => {
    fetchProducts(1, 'replace');
  }, [fetchProducts]);

  const handleLoadMore = useCallback(() => {
    if (isInitialLoading || isRefreshing || isLoadingMore || !hasMore) {
      return;
    }
    fetchProducts(page + 1, 'append');
  }, [fetchProducts, hasMore, isInitialLoading, isLoadingMore, isRefreshing, page]);

  const handleTogglePublish = useCallback(
    async (productId: number, next: boolean) => {
      if (!token) {
        setError('登录状态无效，请重新登录');
        return;
      }
      setUpdatingId(productId);
      try {
        await apiRequest(`/products/${productId}/publish`, {
          method: 'PATCH',
          token,
          body: { is_published: next },
        });
        setProducts((prev) =>
          prev.map((item) => (item.id === productId ? { ...item, is_published: next } : item)),
        );
      } catch (err) {
        const message = err instanceof Error ? err.message : '更新上架状态失败，请稍后再试';
        setError(message);
      } finally {
        setUpdatingId(null);
      }
    },
    [token],
  );

  const handleDelete = useCallback(
    (product: MerchantProduct) => {
      if (!token) {
        setError('登录状态无效，请重新登录');
        return;
      }

      Alert.alert(
        '删除商品',
        `确定要删除「${product.title}」吗？此操作不可撤销。`,
        [
          { text: '取消', style: 'cancel' },
          {
            text: '删除',
            style: 'destructive',
            onPress: async () => {
              try {
                await apiRequest(`/products/${product.id}`, {
                  method: 'DELETE',
                  token,
                });
                setProducts((prev) => prev.filter((item) => item.id !== product.id));
              } catch (err) {
                const message = err instanceof Error ? err.message : '删除失败，请稍后重试';
                setError(message);
              }
            },
          },
        ],
        { cancelable: true },
      );
    },
    [token],
  );

  const handleEdit = useCallback(
    (productId: number) => {
      router.push({
        pathname: '/(merchant)/product/[id]',
        params: { id: String(productId), returnTo: '/(merchant)/products' },
      });
    },
    [router],
  );

  const handleCreate = useCallback(() => {
    router.push({
      pathname: '/(merchant)/product/[id]',
      params: { id: 'new', returnTo: '/(merchant)/products' },
    });
  }, [router]);

  const renderItem: ListRenderItem<MerchantProduct> = ({ item }) => {
    const hero = resolveAssetUrl(
      item.cover_asset?.thumb_url ||
        item.cover_asset?.preview_url ||
        item.cover_asset?.original_url ||
        '',
    );
    return (
      <Pressable style={styles.card} onPress={() => handleEdit(item.id)} onLongPress={() => handleDelete(item)}>
        <View style={styles.cardHeader}>
          {hero ? (
            <Image source={{ uri: hero }} style={styles.cardImage} contentFit="cover" transition={200} />
          ) : (
            <View style={styles.cardImagePlaceholder} />
          )}
          <View style={styles.switchOverlay}>
            <Switch
              value={item.is_published}
              onValueChange={(next) => handleTogglePublish(item.id, next)}
              trackColor={{ true: 'rgba(255,143,177,0.6)', false: '#d8d4db' }}
              thumbColor={item.is_published ? palette.accentDeep : '#f4f3f4'}
              disabled={updatingId === item.id}
            />
          </View>
        </View>
        <View style={styles.cardBody}>
          <Text numberOfLines={1} style={styles.productTitle}>{item.title}</Text>
          <Text numberOfLines={1} style={styles.productType}>{item.type}</Text>
          <View style={styles.cardFooter}>
            <Text style={styles.priceBadge}>¥{item.price.toFixed(2)}</Text>
            <Text style={styles.mutedSmall}>单 {item.orders_count} · ¥{item.total_revenue.toFixed(0)}</Text>
          </View>
        </View>
      </Pressable>
    );
  };

  const listEmptyComponent = (
    <View style={styles.emptyContainer}>
      <Ionicons name="sparkles-outline" size={28} color={palette.accent} />
      <Text style={styles.emptyTitle}>暂未发现商品</Text>
      <Text style={styles.emptySubtitle}>点击下方加号，发布你的首个服务项目</Text>
    </View>
  );

  return (
    <GestureHandlerRootView style={styles.root}>
      <View style={styles.container}>
        <View style={styles.headerTop}>
          <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
            <Text style={styles.title}>商品管理</Text>
            <Link href="/(tabs)" asChild>
              <Pressable style={styles.switchLink} onPress={() => setViewMode('customer')}>
                <Ionicons name="swap-horizontal" size={16} color={palette.accentDeep} />
                <Text style={styles.switchLinkText}>前往 C 端</Text>
              </Pressable>
            </Link>
          </View>
          <Text style={styles.subtitle}>维护商品内容，查看销量与营收表现</Text>
        </View>

        <View style={styles.searchBar}>
          <Ionicons name="search-outline" size={18} color={palette.textMuted} />
          <TextInput
            value={search}
            onChangeText={setSearch}
            placeholder="搜索商品名称或类型"
            placeholderTextColor={palette.textMuted}
            style={styles.searchInput}
          />
        </View>

        {error ? <Text style={styles.errorBanner}>{error}</Text> : null}

        {isInitialLoading ? (
          <View style={styles.loader}>
            <ActivityIndicator size="large" color={palette.accent} />
          </View>
        ) : (
          <FlatList
            data={products}
            keyExtractor={(item) => String(item.id)}
            renderItem={renderItem}
            numColumns={2}
            contentContainerStyle={styles.gridContent}
            columnWrapperStyle={styles.gridRow}
            onEndReached={handleLoadMore}
            onEndReachedThreshold={0.2}
            ListEmptyComponent={listEmptyComponent}
            ListFooterComponent={
              isLoadingMore ? (
                <View style={styles.footerLoader}>
                  <ActivityIndicator size="small" color={palette.accent} />
                  <Text style={styles.footerLoaderText}>加载更多...</Text>
                </View>
              ) : null
            }
            refreshing={isRefreshing}
            onRefresh={handleRefresh}
          />
        )}

        <Pressable style={styles.fab} onPress={handleCreate}>
          <Ionicons name="add" size={28} color="#fff" />
        </Pressable>
      </View>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  root: {
    flex: 1,
  },
  container: {
    flex: 1,
    backgroundColor: palette.background,
    paddingHorizontal: 18,
    paddingVertical: 20,
  },
  headerTop: {
    gap: 6,
    marginBottom: 16,
  },
  title: {
    fontSize: 24,
    fontWeight: '700',
    color: palette.textPrimary,
  },
  subtitle: {
    fontSize: 13,
    color: palette.textMuted,
  },
  switchLink: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 6,
    paddingHorizontal: 6,
    paddingVertical: 4,
  },
  switchLinkText: {
    fontSize: 12,
    color: palette.accentDeep,
    fontWeight: '600',
  },
  searchBar: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 10,
    backgroundColor: palette.surface,
    borderRadius: 18,
    paddingHorizontal: 14,
    paddingVertical: 10,
    borderWidth: 1,
    borderColor: palette.border,
    marginBottom: 12,
  },
  searchInput: {
    flex: 1,
    fontSize: 14,
    color: palette.textPrimary,
  },
  errorBanner: {
    color: palette.danger,
    fontSize: 13,
    marginBottom: 12,
  },
  loader: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  listContent: {
    paddingBottom: 96,
  },
  separator: {
    height: 12,
  },
  productRow: {
    borderRadius: 24,
    backgroundColor: palette.surface,
    borderWidth: 1,
    borderColor: palette.border,
    padding: 16,
    flexDirection: 'row',
    gap: 16,
  },
  gridContent: {
    paddingBottom: 80,
    paddingTop: 8,
  },
  gridRow: {
    justifyContent: 'space-between',
    paddingHorizontal: 4,
    marginBottom: 12,
  },
  card: {
    backgroundColor: palette.surface,
    borderRadius: 16,
    borderWidth: 1,
    borderColor: palette.border,
    overflow: 'hidden',
    width: '48%',
  },
  cardHeader: {
    position: 'relative',
    width: '100%',
    height: 110,
    backgroundColor: 'rgba(0,0,0,0.04)',
  },
  switchOverlay: {
    position: 'absolute',
    top: 8,
    right: 8,
  },
  cardImage: {
    width: '100%',
    height: '100%',
  },
  cardImagePlaceholder: {
    width: '100%',
    height: '100%',
    backgroundColor: 'rgba(214,106,138,0.12)',
  },
  cardBody: {
    paddingHorizontal: 12,
    paddingVertical: 10,
    gap: 6,
  },
  productTitle: {
    fontSize: 16,
    fontWeight: '700',
    color: palette.textPrimary,
  },
  productType: {
    fontSize: 12,
    color: palette.textMuted,
    marginTop: 2,
  },
  cardFooter: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  priceBadge: {
    paddingHorizontal: 10,
    paddingVertical: 4,
    borderRadius: 999,
    backgroundColor: 'rgba(255,143,177,0.18)',
    color: palette.accentDeep,
    fontSize: 12,
    fontWeight: '700',
  },
  mutedSmall: {
    fontSize: 11,
    color: palette.textMuted,
  },
  emptyContainer: {
    paddingVertical: 60,
    alignItems: 'center',
    gap: 10,
  },
  emptyTitle: {
    fontSize: 15,
    fontWeight: '600',
    color: palette.textPrimary,
  },
  emptySubtitle: {
    fontSize: 12,
    color: palette.textMuted,
  },
  footerLoader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 8,
    paddingVertical: 16,
  },
  footerLoaderText: {
    fontSize: 12,
    color: palette.textMuted,
  },
  fab: {
    position: 'absolute',
    bottom: 28,
    alignSelf: 'center',
    backgroundColor: palette.accentDeep,
    width: 58,
    height: 58,
    borderRadius: 29,
    alignItems: 'center',
    justifyContent: 'center',
    shadowColor: '#ff6a9b',
    shadowOpacity: 0.4,
    shadowOffset: { width: 0, height: 8 },
    shadowRadius: 12,
    elevation: 6,
  },
});
